package com.fulu.game.bi.service.impl.channel;

import cn.hutool.core.collection.CollectionUtil;
import com.fulu.game.bi.common.Constants;
import com.fulu.game.bi.common.exception.BizException;
import com.fulu.game.bi.common.util.lang.StringUtils;
import com.fulu.game.bi.entity.enums.GroupRelTableEnum;
import com.fulu.game.bi.entity.po.auth.BiUser;
import com.fulu.game.bi.entity.po.channel.GroupRel;
import com.fulu.game.bi.entity.po.channel.RegistSource;
import com.fulu.game.bi.entity.vo.channel.source.RegisterSourceDisplayVO;
import com.fulu.game.bi.entity.vo.channel.source.RegisterSourceQueryVO;
import com.fulu.game.bi.entity.vo.channel.source.RegisterSourceSaveVO;
import com.fulu.game.bi.enums.CommonlyOrderEnums;
import com.fulu.game.bi.mysql.bi.channel.GroupRelDao;
import com.fulu.game.bi.mysql.bi.channel.RegisterSourceGroupDao;
import com.fulu.game.bi.mysql.playadmin.channel.RegistSourceDao;
import com.fulu.game.bi.redis.service.auth.BiUserService;
import com.fulu.game.bi.redis.service.channel.RegisterSourceService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@Slf4j
public class RegisterSourceServiceImpl implements RegisterSourceService {

    @Autowired
    private RegistSourceDao registSourceDao;
    @Autowired
    private BiUserService biUserService;
    @Autowired
    private GroupRelDao groupRelDao;
    @Autowired
    private RegisterSourceGroupDao registerSourceGroupDao;

    @Override
    public PageInfo<RegisterSourceDisplayVO> list(RegisterSourceQueryVO vo) {
        PageHelper.startPage(vo.getPageNum(), vo.getPageSize(), CommonlyOrderEnums.CREATE_DESC.getValue());

        List<RegisterSourceDisplayVO> registSources = registSourceDao.findByParameter(vo);
        PageInfo<RegisterSourceDisplayVO> pageInfo = new PageInfo<>(registSources);

        pageInfo.getList().forEach(v -> {
            List<GroupRel> groupRelList = groupRelDao.findByRelId(v.getId(), GroupRelTableEnum.REGISTER_SOURCE.getName());
            if (CollectionUtil.isNotEmpty(groupRelList)) {
                List<Integer> groupIdList = groupRelList.stream()
                        .map(GroupRel::getGroupId)
                        .collect(Collectors.toList());

                List<String> name = registerSourceGroupDao.findNameByIds(groupIdList);
                v.setGroupIdList(groupIdList);
                v.setGroupNameList(name);
            }
            BiUser user = Optional.ofNullable(biUserService.findById(v.getAdminId())).orElse(new BiUser());
            v.setAdminName(user.getName());
        });
        return pageInfo;
    }

    @Override
    public List<RegistSource> findByPlatforms(Integer[] platforms) {
        return registSourceDao.findByPlatforms(platforms);
    }

    @Override
    public List<RegistSource> findByNames(String[] names) {
        return registSourceDao.findByNames(names);
    }

    @Override
    public RegistSource save(RegisterSourceSaveVO registSourceVO) {
        if (Objects.isNull(registSourceVO.getId())) {
            return createNewSource(registSourceVO);
        }

        return updateExistSource(registSourceVO);
    }

    public RegistSource save(String name, String remark) {
        BiUser admin = biUserService.getCurrentUser();
        int adminId = admin.getId();
        log.info("调用新增注册来源接口,操作人id={},入参name={},remark={}", adminId, name, remark);
        RegistSource rs = new RegistSource();
        rs.setAdminId(adminId);
        rs.setName(name);
        rs.setRemark(remark);
        rs.setCreateTime(new Date());
        rs.setUpdateTime(new Date());
        String scene = "sourceId=" + rs.getId();
        log.info("调用生成小程序码接口,参数scene={}", scene);
        rs.setWxcodeUrl(Constants.DEFAULT_WORD);
        registSourceDao.insert(rs);
        return rs;
    }

    public int createBatch(List<RegistSource> registerSources) {
        return registSourceDao.createBatch(registerSources);
    }

    @Override
    public int createBatchRel(List<RegistSource> registSources, Map<Integer, Set<Integer>> groupIdsMap) {
        int res = 0;
        List<GroupRel> relList = new ArrayList<>();
        for (RegistSource registSource : registSources) {
            Set<Integer> groupIds = groupIdsMap.get(registSource.getPlatform());
            if (CollectionUtils.isNotEmpty(groupIds)) {
                for (Integer groupId : groupIds) {
                    GroupRel groupRel = new GroupRel();
                    groupRel.setGroupId(groupId);
                    groupRel.setRelId(registSource.getId());
                    relList.add(groupRel);
                }
            }
        }
        if (CollectionUtils.isNotEmpty(relList)) {
            res = groupRelDao.insert(relList, GroupRelTableEnum.REGISTER_SOURCE.getName());
        }
        return res;
    }

    private RegistSource createNewSource(RegisterSourceSaveVO registSourceVO) {
        if (StringUtils.isEmpty(registSourceVO.getName())) {
            throw new BizException("名称不能为空！");
        }
        if (registSourceVO.getPlatform() == null) {
            throw new BizException("渠道号不能为空！");
        }

        registSourceVO.setShouldEdit(true);
        List<RegistSource> platforms = registSourceDao.findByPlatforms(new Integer[]{registSourceVO.getPlatform()});
        if (CollectionUtil.isNotEmpty(platforms)) {
            throw new BizException("渠道号已存在");
        }

        RegistSource existSource = registSourceDao.findByName(registSourceVO.getName());
        if (Objects.nonNull(existSource)) {
            throw new BizException("渠道名已存在");
        }

        Date now = new Date();
        BiUser currentUser = biUserService.getCurrentUser();

        RegistSource registSource = new RegistSource();
        BeanUtils.copyProperties(registSourceVO, registSource);

        registSource.setWechatMerchantId(4);
        registSource.setAlipayMerchantId(1);
        registSource.setCreateTime(now);
        registSource.setUpdateTime(now);
        registSource.setAdminId(currentUser.getId());
        registSourceDao.insert(registSource);

        bindRel(registSourceVO, registSource);
        return registSource;
    }

    private void bindRel(RegisterSourceSaveVO registSourceVO, RegistSource registSource) {
        if (registSourceVO.getShouldEdit()) {
            Integer sourceId = registSource.getId();
            groupRelDao.deleteByRelId(sourceId, GroupRelTableEnum.REGISTER_SOURCE.getName());

            if (StringUtils.isNotEmpty(registSourceVO.getGroupIdList())) {
                String[] groupIdArr = registSourceVO.getGroupIdList().split(",");
                List<GroupRel> relList = Arrays.stream(groupIdArr)
                        .map(Integer::parseInt)
                        .map(groupId -> {
                            GroupRel groupRel = new GroupRel();
                            groupRel.setGroupId(groupId);
                            groupRel.setRelId(sourceId);
                            return groupRel;
                        })
                        .collect(Collectors.toList());

                groupRelDao.insert(relList, GroupRelTableEnum.REGISTER_SOURCE.getName());
            }
        }
    }

    public RegistSource updateExistSource(RegisterSourceSaveVO vo) {

        RegistSource existSource = registSourceDao.findByName(vo.getName());
        if (Objects.nonNull(existSource) && !Objects.equals(existSource.getId(), vo.getId())) {
            throw new BizException("渠道名已存在");
        }

        RegistSource registSource = new RegistSource();
        BeanUtils.copyProperties(vo, registSource);

        registSource.setWechatMerchantId(4);
        registSource.setAlipayMerchantId(1);
        registSource.setUpdateTime(new Date());
        registSourceDao.updateSelective(registSource);

        bindRel(vo, registSource);

        return registSource;
    }

    public RegistSource update(Integer id, String name, String remark) {
        BiUser admin = biUserService.getCurrentUser();
        int adminId = admin.getId();
        log.info("调用注册来源更新接口，入参来源id={}，name={},remark={}", id, name, remark);
        RegistSource rs = registSourceDao.findById(id);
        rs.setUpdateTime(new Date());
        rs.setName(name);
        rs.setRemark(remark);
        rs.setAdminId(adminId);
        registSourceDao.updateSelective(rs);

        return rs;
    }
}
